/**
 * @Author       : Mo 2427995270@qq.com
 * @Date         : 2025-03-29 15:47:22
 * @LastEditTime : 2025-08-22 18:46:39
 * @FilePath     : \GD32F407-DEMO\hal_driver\hal_i2c_slave.h
 * @Description  : 由外部中断驱动的软件模拟i2c从机引擎
 * @Version      : V1.0
 * @History      :
 * @Note         :
 */

#ifndef __hal_i2c_slave_H__
#define __hal_i2c_slave_H__

/***************************************Includes***********************************/
#include "ll_exti.h"


/*************************************Public Macros********************************/
#define I2C_SLAVE_STATUS_SCL 0X02
#define I2C_SLAVE_STATUS_SDA 0X01
#define I2C_SLAVE_STATUS_START 0X04
#define I2C_SLAVE_STATUS_ACCEPT 0X08
#define I2C_SLAVE_STATUS_ACK 0x10


/***********************************Public Statement*******************************/
struct i2c_slave_dev;
typedef struct i2c_slave_dev i2c_slave_dev_t;
struct i2c_slave_transfer_data;
typedef struct i2c_slave_transfer_data i2c_slave_transfer_data_t;

typedef int (*i2c_slave_receive_cb_t)(i2c_slave_dev_t *dev, const i2c_slave_transfer_data_t *trdata, void *arg);
// 返回0继续 -1终止传输，回调里不要做任何耗时的操作，只需对trdata的成员赋值即可
typedef int (*i2c_slave_request_cb_t)(i2c_slave_dev_t *dev, i2c_slave_transfer_data_t *trdata, void *arg);

typedef struct {
    uint32_t port_scl;               // SCL端口
    uint32_t port_sda;               // SDA端口
    uint32_t pinnum_scl;             // SCL管脚号
    uint32_t pinnum_sda;             // SDA管脚号
    uint32_t cfg_interrupt_priority; // 抢占中断优先级 建议优先级分组设置为4组，4位抢占
    uint8_t *receive_buf;            // 接收缓存指针 主机有写入操作时，必须设置
    uint32_t receive_buf_size;       // 接收缓存大小
    // 驱动服务函数在什么地方调用，事件回调就在哪调用，注意中断是否受系统管理，和使用系统相关函数
    i2c_slave_receive_cb_t receive_cb; // 接收完成事件函数
    i2c_slave_request_cb_t request_cb; // 请求事件回调
    void *arg;                         // 用户参数
} i2c_slave_config_t;

struct i2c_slave_transfer_data {
    uint8_t *data;
    uint32_t len;
};

struct i2c_slave_dev {
    uint8_t dev_addr;                       // 7位 不包含读写位
    uint8_t dev_addr_mask;                  // 设备地址掩码
    exti_ll_t exti_scl;                     // scl引脚
    exti_ll_t exti_sda;                     // sda引脚
    uint8_t *receive_buf;                   // 接收缓存指针 主机有写入操作时，必须设置
    uint32_t receive_buf_size;              // 接收缓存大小
    uint32_t __status;                      // 状态
    uint8_t transfer_addr;                  // 传输地址
    uint32_t transfer_cnt;                  // 传输计数
    uint32_t transfer_len;                  // 传输长度
    void *arg;                              // 用户参数
    i2c_slave_receive_cb_t receive_cb;      // 接收回调函数
    i2c_slave_request_cb_t request_cb;      // 请求回调函数
    i2c_slave_transfer_data_t request_data; // 请求的数据
};


/***********************************Public Functions*******************************/

/**
 * @brief i2c从机设备初始化
 * @param  dev
 * @param  dev_addr         设备地址 7位 不含读写位
 * @param  config           i2c设备配置
 * @return int 0成功 -1失败
 * @note
 */
int i2c_slave_dev_init(i2c_slave_dev_t *dev, int dev_addr, i2c_slave_config_t *config);





/***************************************Public Variables**********************************/


#endif
/* [] END OF FILE */
